package gee

import (
	"fmt"
	"log"
	"strings"
)

type router struct {
	roots    map[string]*node
	handlers map[string]HandlerFunc
}

type node struct {
	pattern  string
	part     string
	children []*node
	iswild   bool
}

func newRouter() *router {
	return &router{
		roots:    make(map[string]*node),
		handlers: make(map[string]HandlerFunc)}
}

func (r *router) addRoute(method string, pattern string, handler HandlerFunc) {

	key := method + "-" + pattern
	_, ok := r.roots[method]
	if !ok {
		r.roots[method] = &node{}
	}
	r.roots[method].insert(pattern, 0)
	r.handlers[key] = handler
	log.Printf("Route %4s - %s", method, pattern)
}

func (r *router) getRoute(method string, pattern string) (*node, map[string]string) {

	rootnode, ok := r.roots[method]
	if !ok {
		return nil, nil
	}
	params := make(map[string]string)
	node := rootnode.search(pattern, 0)
	if node != nil {
		for index, part := range parsePath(node.pattern) {
			if part[0] == ':' {
				params[part[1:]] = parsePath(pattern)[index]
			}
			if part[0] == '*' {
				params[part[1:]] = strings.Join(parsePath(pattern)[index:], "/")
				break
			}
		}
		fmt.Printf("node:%+v ,params:%v\n", node, params)
		return node, params
	}
	return nil, nil
}

func (r *router) handle(c *Context) {
	n, p := r.getRoute(c.Method, c.Path)
	if n != nil {
		c.Params = p
		key := c.Method + "-" + n.pattern
		c.handlers = append(c.handlers, r.handlers[key])

	} else {
		c.handlers = append(c.handlers, func(ctx *Context) {
			c.String(404, "404 NOT FOUND: %s\n", c.Path)
		})
	}
	c.Next()
}

func (r *router) GET(path string, handle HandlerFunc) {
	r.addRoute("GET", path, handle)
}

func (n *node) insert(pattern string, level int) {

	parts := parsePath(pattern)

	//parts[0]=="" 对应”/“路径的情况
	if len(parts) == 0 || len(parts) == level { //已经解析到最后一层
		n.pattern = pattern
		fmt.Printf("%+v\n", n)
		return
	}
	part := parts[level]
	if part == "" {
		return
	}
	child := n.matchchild(part)
	if child == nil { //没有找到对应的子node，新建一个子节点
		child = &node{part: part, iswild: part[0] == ':' || part[0] == '*'}
		n.children = append(n.children, child)
	}

	child.insert(pattern, level+1)

}
func (n *node) search(pattern string, level int) *node {
	results := make(map[int]*node)
	parts := parsePath(pattern)
	//parts[0]=="" 对应”/“路径的情况
	if len(parts) == 0 {
		return n
	}
	if len(parts) == level || strings.Contains(n.part, "*") { //已经解析到最后一层
		if (parts[level-1] == n.part || n.iswild) && n.pattern != "" {
			return n
		} else {
			return nil
		}
	}
	part := parts[level]
	children := n.matchchildren(part)
	for _, child := range children {
		result := child.search(pattern, level+1)
		if result != nil {
			if strings.Contains(result.pattern, ":") {
				results[2] = result
			} else if strings.Contains(result.pattern, "*") {
				results[3] = result
			} else {
				results[1] = result
			}

		}
	}
	if _, ok := results[1]; ok {
		return results[1]
	} else if _, ok = results[2]; ok {
		return results[2]
	} else if _, ok = results[3]; ok {
		return results[3]
	} else {
		return nil
	}
}
func (n *node) matchchild(part string) *node {
	for _, child := range n.children {
		if child.part == part {
			return child
		}
	}
	return nil
}

func (n *node) matchchildren(part string) []*node {
	nodes := make([]*node, 0)
	for _, child := range n.children {
		if child.part == part || child.iswild {
			nodes = append(nodes, child)
		}
	}
	return nodes
}

func parsePath(p string) []string {
	// if p == "" || p[0] != '/' {
	// 	panic("路径非法，要以/开始")
	// }

	// str := strings.Split(p, "/")
	// return str
	vs := strings.Split(p, "/")

	parts := make([]string, 0)
	for _, item := range vs {
		if item != "" {
			parts = append(parts, item)

		}
	}
	return parts
}
